package com.moss.cloud.base.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moss.cloud.base.api.model.from.BaseFrom;
import com.moss.cloud.base.api.model.from.PositionCodeFrom;
import com.moss.cloud.base.api.model.param.PositionCodeParam;
import com.moss.cloud.base.biz.mapper.SysPositionCodeMapper;
import com.moss.cloud.base.biz.model.SysPositionCode;
import com.moss.cloud.base.biz.service.ISysPositionCodeService;
import com.moss.cloud.base.biz.service.ISysPositionService;
import com.moss.cloud.common.base.utils.PageUtil;
import com.moss.cloud.common.core.exception.SystemErrorType;
import com.moss.cloud.common.core.utils.BooleanHandel;
import com.moss.cloud.common.core.utils.UserContextHolder;
import com.moss.cloud.common.security.annotation.RequiresTenant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 职位管理业务实现
 *
 * @author 瑾年
 * @date 2023年12月18日
 */
@Slf4j
@Service
public class SysPositionCodeServiceImpl extends ServiceImpl<SysPositionCodeMapper, SysPositionCode> implements ISysPositionCodeService {

    private final ISysPositionService sysPositionService;

    public SysPositionCodeServiceImpl(ISysPositionService sysPositionService) {
        this.sysPositionService = sysPositionService;
    }

    /**
     * 职位代号分页数据
     *
     * @param positionCodeParam
     * @return
     */
    @Override
    @RequiresTenant
    public IPage<SysPositionCode> positionCodeList(PositionCodeParam positionCodeParam) {
        Page<SysPositionCode> page = PageUtil.createPage(positionCodeParam.getCurrent(), positionCodeParam.getSize());
        return this.page(page, new QueryWrapper<SysPositionCode>().lambda()
                .eq(StringUtils.isNotBlank(positionCodeParam.getCodeName()), SysPositionCode::getCodeName, positionCodeParam.getCodeName())
                .eq(StringUtils.isNotBlank(positionCodeParam.getPositionCode()), SysPositionCode::getPositionCode, positionCodeParam.getPositionCode())
                .eq(SysPositionCode::getTenantId, UserContextHolder.getTenantId()));
    }

    /**
     * 新增职位代号
     *
     * @param positionCodeFrom
     * @return
     */
    @Override
    @RequiresTenant
    @Transactional(rollbackFor = Exception.class)
    public boolean savePositionCode(PositionCodeFrom positionCodeFrom) {
        this.checkCode(positionCodeFrom, Boolean.TRUE);
        SysPositionCode positionCode = new SysPositionCode();
        BeanUtils.copyProperties(positionCodeFrom, positionCode);
        positionCode.setTenantId(UserContextHolder.getTenantId());
        return this.save(positionCode);
    }

    /**
     * 更新职位代号
     *
     * @param positionCodeFrom
     * @return
     */
    @Override
    @RequiresTenant
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePositionCode(PositionCodeFrom positionCodeFrom) {
        BooleanHandel.trueThrow(Objects.isNull(positionCodeFrom.getId())).throwMessage(SystemErrorType.DATE_EMPTY);
        this.checkCode(positionCodeFrom, Boolean.FALSE);
        SysPositionCode positionCode = new SysPositionCode();
        BeanUtils.copyProperties(positionCodeFrom, positionCode);
        return this.updateById(positionCode);
    }

    /**
     * 检验code不能重复
     *
     * @param positionCodeFrom
     */
    private void checkCode(PositionCodeFrom positionCodeFrom, boolean isAdd) {
        List<SysPositionCode> positionCodes = this.list(new QueryWrapper<SysPositionCode>().lambda()
                .eq(SysPositionCode::getTenantId, UserContextHolder.getTenantId())
                .eq(SysPositionCode::getPositionCode, positionCodeFrom.getPositionCode()));
        BooleanHandel.trueThrow(isAdd && CollectionUtils.isNotEmpty(positionCodes)).throwMessage(SystemErrorType.POSITION_CODE_REPEAT);
        BooleanHandel.isTrue(!isAdd).trueHandle(() -> {
            positionCodes.removeIf(item -> item.getId().equals(positionCodeFrom.getId()));
            BooleanHandel.trueThrow(CollectionUtils.isNotEmpty(positionCodes)).throwMessage(SystemErrorType.POSITION_CODE_REPEAT);
        });
    }

    /**
     * 删除职位代号
     *
     * @param baseFrom
     * @return
     */
    public boolean removePositionCode(BaseFrom baseFrom) {
        SysPositionCode sysPositionCode = this.getById(baseFrom.getId());
        BooleanHandel.trueThrow(Objects.isNull(sysPositionCode)).throwMessage(SystemErrorType.DATE_EMPTY);
        long count = sysPositionService.positionByCode(sysPositionCode.getPositionCode());
        BooleanHandel.trueThrow(count > 0).throwMessage(SystemErrorType.POSITION_CODE_USED);
        return this.removeById(baseFrom.getId());
    }
}
